package com.course02.order_backend.validation.Ost.validator;

import com.course02.order_backend.validation.Ost.annotation.IdCard;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;

public class IdCardValidator implements ConstraintValidator<IdCard, String> {
    private static final String ID_CARD_REGEX = "^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
    private static final Pattern ID_CARD_PATTERN = Pattern.compile(ID_CARD_REGEX);
    private static final int[] WEIGHT = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
    private static final char[] CHECK_CODE = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null || value.trim().isEmpty()) {
            return true;
        }
        if (!ID_CARD_PATTERN.matcher(value).matches()) {
            return false;
        }
        return validateCheckCode(value);
    }

    private boolean validateCheckCode(String idCard) {
        try {
            int sum = 0;
            for (int i = 0; i < 17; i++) {
                sum += Character.getNumericValue(idCard.charAt(i)) * WEIGHT[i];
            }
            int remainder = sum % 11;
            char expectedCode = CHECK_CODE[remainder];
            char actualCode = Character.toUpperCase(idCard.charAt(17));
            return expectedCode == actualCode;
        } catch (Exception e) {
            return false;
        }
    }
}